package com.ruoyi.web.controller.system;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.base.AjaxResult;
import com.ruoyi.common.constant.CacheKeyConstants;
import com.ruoyi.common.constant.ResultConstants;
import com.ruoyi.common.sms.wlwx.client.SmsClientMain;
import com.ruoyi.common.utils.*;
import com.ruoyi.framework.util.MyConstants;
import com.ruoyi.framework.web.base.BaseController;
import com.ruoyi.framework.web.base.Result;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 登录验证
 * 
 * @author ruoyi
 */
@Controller
public class SysLoginController extends BaseController
{

    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private ISysUserService userService;



    @GetMapping("/login")
    public String login(HttpServletRequest request, HttpServletResponse response)
    {
        // 如果是Ajax请求，返回Json字符串。
        if (ServletUtils.isAjaxRequest(request))
        {
            return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
        }

        return "login";
    }

    @PostMapping("/login")
    @ResponseBody
    public AjaxResult ajaxLogin(HttpServletRequest request, HttpServletResponse response, String username, String password, Boolean rememberMe ,String mobileCode)
    {
        // 获取发起电脑 ip

        String msg=null;
        String visitIp = null;
        // 判断是否为外网访问,获取访问者IP地址
//        try {
//            visitIp = getIpAddress(request);
//        } catch (IOException e) {
//            log.error( "获取ip地址异常",e);
//        }


        if(isProdEnv()){
            if(StringUtils.isEmpty(mobileCode)){
                msg = "请输入短信验证码";
                return error(msg);
            }
            String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.ADMIN_SMS_CODE_TPL, username, MyConstants.SMS_CODE_TYPE.LOGIN);
            String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
            if(!mobileCode.equals(smsCode)){
                msg = "短信验证码不正确";
                return error(msg);
            }
        }

        UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe,visitIp);
        Subject subject = SecurityUtils.getSubject();
        try
        {
            subject.login(token);
            return success();
        }
        catch (AuthenticationException e)
        {
             msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage()))
            {
                msg = e.getMessage();
            }
            return error(msg);
        }
    }

    @GetMapping("/unauth")
    public String unauth()
    {
        return "/error/unauth";
    }


    @PostMapping(value = "/getLoginSmsCodeWLWX")
    @ResponseBody
    public Result getLoginSmsCodeWLWX(String userName)throws Exception {
        //检查参数合法性

//        if(StringUtils.isEmpty(mobile)) {
//            return Result.error(ResultConstants.FI1000, "手机号不能为空");
//        }
//        if(!mobile.matches(Constants.MOBILE_PATTERN)) {
//            return Result.error(ResultConstants.FI1000, "手机号格式错误");
//        }
        SysUser user = userService.selectUserByLoginName(userName);
        if(user == null) {
            return Result.error(ResultConstants.FI2000, "用户不存在");
        }
        String phoneNumber = AESUtil.decrypt(user.getPhonenumber());
        if(StringUtils.isEmpty(user.getPhonenumber()) || StringUtils.isEmpty(phoneNumber)) {
            return Result.error(ResultConstants.FI2000, "用户未绑定手机号");
        }

        String smsCodeCacheKey = CacheKeyConstants.getTempletString(CacheKeyConstants.ADMIN_SMS_CODE_TPL, userName, MyConstants.SMS_CODE_TYPE.LOGIN);
        String smsCode = (String) redisTemplate.opsForValue().get(smsCodeCacheKey);
        if(StringUtils.isNotEmpty(smsCode)) {
            log.info("smsCode:{}", smsCode);
            return Result.error(ResultConstants.FI3002, "验证码未过期 有效期五分钟");
        }
        //过期了,就再次发送短信
        smsCode = RandomStringUtils.getNumber(4);
        String content = String.format(MessageUtils.message("msg.content"), smsCode);
        String resultMsg = SmsClientMain.getReportResultMsg(phoneNumber, content);
        JSONObject jsonObject=JSONObject.parseObject(resultMsg);
        if ("0".equals(jsonObject.get("respCode"))) {
            redisTemplate.opsForValue().set(smsCodeCacheKey, smsCode, MyConstants.CONFIG.SMS_CODE_TIMEOUT, TimeUnit.SECONDS);
            log.info("smsCode:{}", smsCode);
            return Result.ok("短信获取成功" + jsonObject.get("respMsg"));
        } else {
            /**
             *  1000：服务器出现未知异常！
             *  1001 操作不合法，操作前未获取Token，或Token已过时
             *	1002 签名验证不通过！
             *	1003 Json参数解析出错
             *	1004 操作不合法，cust_code: xxxxxx不存在
             *	1005 客户端IP鉴权不通过
             *	1006 客户账号已停用！
             *	1008 客户提交接口协议HTTPS, 与客户参数允许的协议不一致！
             *	1009 提交的短信内容超过规定的长度！
             *	1011 客户账户不存在！
             *	1012 账户没有足够的余额
             *	1013 扩展号码(sp_code)不符合规范！
             */
            return Result.error(MyConstants.RESULT.FI1000,"发送失败");
        }
    }
}
